from tw.api import Widget

__all__ = ["Site"]

class Site(Widget):
	""" 
	A widget to Build a template on the fly based on Slot atributes of Grups of Widgets.
	It also build a Tree of the HTML structure. It can be used after instantation.
	Slots are positional attributes, like slot='header.logo.component' where each word must be unique.
	The last word in the ( separated by "." ) is the name of the Container for a grup of Widget.
	Take a look at the Grup Widget Definition for furter understanding.
	
	>>>	from tw.api import Widget, WidgetsList
	>>> from tw.lymon inport Site, Grup
	>>>
	>>>	class Component1(WidgetsList):
	>>>		w1 = Widget(template='''<p>W1 Cmp1</p>''')
	>>>		w2 = Widget(template='''<p>W2 Cmp1</p>''')
	>>>		w3 = Widget(template='''<p>W3 Cmp1</p>''')

	>>>	class Component2(WidgetsList):
	>>>		w1 = Widget(template='''<p>W1 Cmp2</p>''')
	>>>		w2 = Widget(template='''<p>W2 Cmp2</p>''')
	>>>		w3 = Widget(template='''<p>W3 Cmp2</p>''')

	>>>
	>>> grup1 = Grup(slot='header.logo.component1', children=Component1())	
	>>> grup2 = Grup(slot='footer.markup.component2', children=Component2())
	>>>
	>>> site = Site(grups=[grup1,grup2])
	>>> print site.tree
	{'header': {'logo': {'component1': {}}}, 'footer': {'markup': {'component2': {}}}}
	>>>
	>>> print site.display()
	>>>
	<div id="site">
	<div id="header">
		<div id="logo">
			<div id="component1">
				<p>W1 Cmp1</p><p>W2 Cmp1</p><p>W3 Cmp1</p>
			</div>
		</div>
	</div>
	<div id="footer">
		<div id="markup">
			<div id="component2">
				<p>W1 Cmp2</p><p>W2 Cmp2</p><p>W3 Cmp2</p>
			</div>
		</div>
	</div>
	</div>
	
	"""
	params = ['grups','preTemplate']
	preTemplate = ""
	engine_name = 'genshi'
	template = ""
	tree = {}
	
	def __init__(self,*k,**kw):
		super(Site, self).__init__(*k,**kw)
		# !! Needs to fix when grups is empty
		try:
			
			self.grups = dict([(k.id, k) for k in kw['grups']])
		except KeyError:
			raise KeyError, "You must provide a grups atribute ( list of widgets )"
		preTemplate = self.render(self.grups)
		self.template = """<div xmlns:py="http://genshi.edgewall.org/" id='site'>\n%s\n</div>""" % (preTemplate)
		
	def render(self, grups):
		# Make a list of each last slot component. slot = "a.b.c" => display=['c']
		display = [key for key in grups.keys()]
		slots = [grup.slot for grup in grups.values()]
		tree = self.makeTree(slots)
		self.tree = tree
		return  self.renderTree(tree=tree, display=display)
		
	def updateTree(self, tree, slot):
		"""
		Return a Tree as a dictionary from a given Slot ( slot = "a.b...z")
		>> tree=Tree()
		>> print tree.updateTree(tree={},'a.b.c')
		{'a': {'b': {'c': {}}}}
		"""
		if type(slot) == str:
			slot = slot.split('.')
		d = tree
		while slot:
			head = slot.pop(0)
			d = d.setdefault(head,{})
		tree.update(d)
		return tree

	def makeTree(self, slots=[]):
		"""
		Build a tree from a given Slot List
		>> tree=Tree()
		>> print tree.makeTree(slots=['a.b.c', 'a.b.d'])
		{'a': {'b': {'c': {}, 'd': {}}}}
		"""
		if type(slots) == list:
			tree = {}
			while slots:
				slot = slots.pop(0)
				tree = self.updateTree(tree, slot)
			return tree

	def renderTree(self, tree={}, deep=0, display=[]):
		"""
		Render a template for a given tree, using recursive calls.
		>> tree=Tree()
		>> toRender = tree.makeTree(slots=['a.b.c', 'a.b.d'])
		>> print toRender
		{'a': {'b': {'c': {}, 'd': {}}}}
		print tree.renderTree(toRender, display=['a','d'])
		<div id='a'>
			<div id='b'>
				<div id='c'>
				</div>
				<div id='d'>
					${d()}
				</div>
			</div>
			${a()}
		</div>
		"""
		q = tree.keys()
		template = ""
		while q:
			head = q.pop(0)
			template += (deep * "\t") + ("<div id='%s'>\n" % (head) + "%s" )
			if head in display:
				template += (deep * "\t") + "\t${grups['%s'](displays_on='genshi')}\n" % head 
			item = tree[head]
			# deep control the Tab, increase for each recusive call.
			deep += 1
			template = template % (self.renderTree(item, deep, display))
			deep -= 1
			template += ((deep) * "\t") + "</div>\n"
		return template
		
		
		
		
		
		
		
